home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / motif / otessellate.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  11KB  |  415 lines

  1. /*
  2.  * Copyright (c) 1993-94, Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that the name of Silicon Graphics may not be used in any advertising or
  7.  * publicity relating to the software without the specific, prior written
  8.  * permission of Silicon Graphics.
  9.  *
  10.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  11.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  12.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  13.  *
  14.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  15.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  16.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  17.  * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
  18.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19.  *
  20.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  21.  */
  22. /*----------------------------------------------------------------------------
  23.  *
  24.  * otessellate.c : openGL (motif) example showing how to tessellate
  25.  *                 concave polygons and polygons with holes
  26.  *
  27.  * Author : Yusuf Attarwala
  28.  *          SGI - Applications
  29.  * Date   : Sep 93
  30.  *
  31.  *    press  left   button for animation
  32.  *    press  middle button to turn OFF tessellation
  33.  *    press  right  button to turn ON  tessellation
  34.  *
  35.  *---------------------------------------------------------------------------*/
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39.  
  40. #include <Xm/Xm.h> 
  41. #include <Xm/Frame.h>               /* for frame widgets */
  42. #include <Xm/Form.h>                /* for form  widgets */
  43. #include <X11/keysym.h>             /* keyboard translations */
  44. #include <X11/StringDefs.h>
  45.  
  46. #include <GL/gl.h>                  /* gl includes */
  47. #include <GL/glu.h>                 /* utility library includes */
  48. #include <GL/GLwMDrawA.h>           /* include for the drawing area widget */
  49.  
  50. static int tessellationOn = 0;
  51.  
  52. /* function declarations */
  53.  
  54. void 
  55.     createToplevel(void),
  56.     drawScene(void),
  57.     setMatrix(void),
  58.     animation(void),
  59.     doTessellation(void),
  60.     exposeCB(Widget,XtPointer,XtPointer),
  61.     resizeCB(Widget,XtPointer,XtPointer),
  62.     initCB(Widget,XtPointer,XtPointer),
  63.     inputCB(Widget,XtPointer,XtPointer);
  64.  
  65. /* callback functions for tessellator */
  66. void
  67.     myBegin(GLenum),
  68.     myVertex(void *),
  69.     myEnd(void),
  70.     myError(GLenum);
  71.  
  72. /* global variables */
  73.             
  74. Display       *display;       /* current display */
  75. XtAppContext  appContext;     /* X application context */
  76. float         ax,ay,az;       /* angles for animation */
  77.  
  78. Widget        toplevel,       /* toplevel shell */
  79.               glw;            /* current widget */
  80.              
  81. GLXContext    glxc;           /* current glx context */
  82.  
  83. Arg args[20];
  84. int acnt;
  85.  
  86. /* coords of outer star  */
  87.  
  88. static GLfloat outerColor[3] = {1.0,1.0,0.0};
  89.  
  90. static int nouter = 10;
  91. static GLfloat   outer[10][3] = {3.5,5.0,0.0,
  92.                                  2.0,2.0,0.0,
  93.                                  5.0,4.0,0.0,
  94.                                  8.0,2.0,0.0,
  95.                                  6.5,5.0,0.0,
  96.                                  8.0,6.0,0.0,
  97.                                  6.0,6.0,0.0,
  98.                                  5.0,8.0,0.0,
  99.                                  4.0,6.0,0.0,
  100.                                  2.0,6.0,0.0};
  101.  
  102. /* coords of inner star  */
  103.  
  104. static int ninner = 10;
  105. static GLfloat inner[10][3] = {3.8,5.0,0.0,
  106.                    2.6,2.6,0.0,
  107.                    5.0,4.2,0.0,
  108.                    7.4,2.6,0.0,
  109.                    6.2,5.0,0.0,
  110.                    7.4,5.8,0.0,
  111.                    5.8,5.8,0.0,
  112.                    5.0,7.4,0.0,
  113.                    4.2,5.8,0.0,
  114.                    2.6,5.8,0.0};
  115.  
  116.  
  117. /* display list identifier */
  118. GLuint tList = 1;
  119.  
  120. void 
  121. main(int argc, char** argv)
  122. {
  123.     XtToolkitInitialize();
  124.     appContext = XtCreateApplicationContext();
  125.     display    = XtOpenDisplay(appContext, NULL, "Otessellate","otessellate",NULL,0,
  126.                               &argc,argv);
  127.     if (!display) {
  128.         printf("%s : Unable to open display\n",argv[0]);
  129.         exit(0);
  130.     }
  131.  
  132.     printf("\n---------------------------------------------\n");
  133.     printf("OpenGL tessellation example \n\n");
  134.     printf("Press:  left   button for animation\n\
  135.         middle button to turn OFF tessellation (default)\n\
  136.         right  button to turn ON  tessellation \n");
  137.  
  138.     createToplevel();             /* create widget hierarchy */
  139.     XtAppMainLoop(appContext);    /* loop forever */
  140. }
  141.  
  142.  
  143. void
  144. createToplevel(void)
  145. {
  146.     Widget frame;
  147.  
  148.     acnt = 0;
  149.     XtSetArg(args[acnt],XmNminHeight, 300);acnt++;
  150.     XtSetArg(args[acnt],XmNminWidth,  300);acnt++;
  151.     XtSetArg(args[acnt],XmNminAspectX,  1);acnt++;
  152.     XtSetArg(args[acnt],XmNminAspectY,  1);acnt++;
  153.     XtSetArg(args[acnt],XmNmaxAspectX,  1);acnt++;
  154.     XtSetArg(args[acnt],XmNmaxAspectY,  1);acnt++;
  155.     toplevel  = XtAppCreateShell("openGL tessellate","otessellate",
  156.                                   applicationShellWidgetClass,
  157.                                   display,args,acnt);
  158.  
  159.     /* create a frame to hold glx widget */
  160.     frame   = XtVaCreateManagedWidget("frame", 
  161.                   xmFrameWidgetClass, toplevel, 
  162.                   NULL);
  163.  
  164.     /* create a double buffer widget, in rgb mode and manage it */
  165.     acnt = 0;
  166.     XtSetArg(args[acnt], GLwNrgba,               TRUE); acnt++;
  167.     XtSetArg(args[acnt], GLwNdoublebuffer,       TRUE); acnt++;
  168.     XtSetArg(args[acnt], GLwNallocateBackground, TRUE); acnt++;
  169.     glw = GLwCreateMDrawingArea(frame, "glw", args, acnt);
  170.     XtManageChild(glw);
  171.  
  172.     /* register callbacks */
  173.     XtAddCallback(glw, GLwNginitCallback,  initCB,   NULL);
  174.  
  175.     /* realize widget hierarchy */
  176.     XtRealizeWidget(toplevel);
  177.  
  178.     /* additional callbacks */
  179.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
  180.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
  181.     XtAddCallback(glw, GLwNinputCallback,  inputCB,  NULL);
  182.  
  183. }
  184.  
  185. void
  186. drawScene(void)
  187. {
  188.  
  189.     int i;
  190.  
  191.     glClearColor(0.0, 0.0, 0.0, 0.0);
  192.     glClear(GL_COLOR_BUFFER_BIT);
  193.  
  194.     glPushMatrix();
  195.  
  196.     glTranslatef(4.0,4.0,0.0);
  197.     glRotatef (ax,1.0,0.0,0.0);
  198.     glRotatef (-ay,0.0, 1.0, 0.0);
  199.     glRotatef (az,0.0, 0.0, 1.0);
  200.     glTranslatef(-4.0,-4.0,0.0);
  201.  
  202.     /* all the good stuff follows */
  203.  
  204.     if (tessellationOn) {
  205.     /* draw the tessellated polygons (stored in display list) */
  206.     glCallList(tList);
  207.     }
  208.     else {
  209.     /* draw the original polygons */
  210.     glColor3fv(outerColor);
  211.     glBegin(GL_LINE_LOOP);
  212.         for (i=0;i<nouter;i++) {
  213.         glVertex3fv((GLfloat *)outer[i]);
  214.         }
  215.     glEnd();
  216.  
  217.     glBegin(GL_LINE_LOOP);
  218.         for (i=0;i<ninner;i++) {
  219.         glVertex3fv((GLfloat *)inner[i]);
  220.         }
  221.     glEnd();
  222.     }
  223.  
  224.     /* end of good stuff */
  225.     glPopMatrix();
  226.  
  227.     glFlush();
  228.     glXSwapBuffers(XtDisplay(glw), XtWindow(glw));
  229.  
  230. }
  231.  
  232. void
  233. setMatrix(void)
  234. {
  235.     glMatrixMode(GL_PROJECTION);
  236.     glLoadIdentity();
  237.     glOrtho(-0.5,9.5,-0.5,9.5,-10.0,10.0);
  238.     glMatrixMode(GL_MODELVIEW);
  239.     glLoadIdentity();
  240. }
  241.  
  242. void
  243. animation(void)
  244. {
  245.     register int i;
  246.     /* animate the star */
  247.  
  248.     for (i=0;i<60;i++) {
  249.     /*
  250.         ax += 1.5;
  251.         ay -= 2.5;
  252.     */
  253.         az += 3.0;
  254.         if (ax >= 360)  ax = 0.0;
  255.         if (ay <= -360) ay = 0.0;
  256.         if (az >= 360)  az = 0.0;
  257.         drawScene();
  258.     }
  259. }
  260.  
  261. void 
  262. inputCB(Widget w, XtPointer client_data, XtPointer call)
  263. {
  264.     static int firstTime = 1;
  265.     char            string[31];
  266.     XComposeStatus  composeStatus;
  267.     KeySym keysym;
  268.     GLwDrawingAreaCallbackStruct *call_data;
  269.  
  270.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  271.  
  272.     switch(call_data->event->type) {
  273.     case ButtonPress:
  274.         switch (call_data->event->xbutton.button) {
  275.         case Button1:
  276.         animation();
  277.             break;
  278.         case Button2 :
  279.         tessellationOn = 0;
  280.         XtVaSetValues(toplevel,XmNtitle, "No Tessellation",NULL);
  281.         drawScene();
  282.             break;
  283.         case Button3 :
  284.         tessellationOn = 1;
  285.         if (firstTime) {
  286.         firstTime = 0;
  287.         doTessellation();
  288.         }
  289.         XtVaSetValues(toplevel,XmNtitle, "Tessellated Polygons",NULL);
  290.         drawScene();
  291.             break;
  292.         }
  293.         break;
  294.     case KeyPress :
  295.         XLookupString((XKeyEvent *)call_data->event,string,
  296.                       30,&keysym,&composeStatus);
  297.         switch(keysym) {
  298.         case XK_Escape :
  299.             exit(0);
  300.             break;
  301.         }
  302.     break;
  303.     default:
  304.         break;
  305.     }
  306. }
  307.  
  308. void 
  309. resizeCB(Widget w, XtPointer client_data, XtPointer call)
  310. {
  311.     GLwDrawingAreaCallbackStruct *call_data;
  312.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  313.  
  314.     GLwDrawingAreaMakeCurrent(w, glxc);
  315.     glViewport(0, 0, call_data->width, call_data->height);
  316.     setMatrix();
  317.  
  318.     drawScene();
  319. }
  320.  
  321. void 
  322. exposeCB(Widget w, XtPointer client_data, XtPointer call)
  323. {
  324.     GLwDrawingAreaCallbackStruct *call_data;
  325.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  326.  
  327.  
  328.     GLwDrawingAreaMakeCurrent(w, glxc);
  329.     glViewport(0, 0, call_data->width, call_data->height);
  330.     drawScene();
  331. }
  332.  
  333. void
  334. initCB(Widget w, XtPointer client_data, XtPointer call)
  335. {
  336.     XVisualInfo *vi;
  337.  
  338.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  339.     XtGetValues(w, args, 1);
  340.  
  341.     glxc = glXCreateContext(XtDisplay(w), vi, 0, GL_TRUE);
  342.  
  343.     ax = 10.0;
  344.     ay = -10.0;
  345.     az = 0.0;
  346. }
  347.  
  348. void
  349. doTessellation()
  350. {
  351.     int i;
  352.     GLUtriangulatorObj *tobj;
  353.     GLdouble db3[3];
  354.  
  355.     /* create a tessellation object */
  356.     tobj = gluNewTess();
  357.  
  358.     /* register callbacks */
  359.     gluTessCallback(tobj,GLU_BEGIN, myBegin);
  360.     gluTessCallback(tobj,GLU_VERTEX,myVertex);
  361.     gluTessCallback(tobj,GLU_END,   myEnd);
  362.     gluTessCallback(tobj,GLU_ERROR, myError);
  363.  
  364.     glNewList(tList,GL_COMPILE);
  365.     glColor3fv(outerColor);
  366.  
  367.     gluBeginPolygon(tobj);
  368.     for (i=0;i<nouter;i++) {
  369.     db3[0] = (GLdouble) outer[i][0];
  370.     db3[1] = (GLdouble) outer[i][1];
  371.     db3[2] = (GLdouble) outer[i][2];
  372.     gluTessVertex(tobj,(GLdouble *)db3,(void *)outer[i]);
  373.     }
  374.     gluNextContour(tobj,GLU_INTERIOR);
  375.     for (i=0;i<ninner;i++) {
  376.     db3[0] = (GLdouble) inner[i][0];
  377.     db3[1] = (GLdouble) inner[i][1];
  378.     db3[2] = (GLdouble) inner[i][2];
  379.     gluTessVertex(tobj,(GLdouble *)db3,(void *)inner[i]);
  380.     }
  381.     gluEndPolygon(tobj);
  382.  
  383.     glEndList();
  384.  
  385.     /* free the tess obj, when done */
  386.     gluDeleteTess(tobj);
  387. }
  388.  
  389. void
  390. myBegin(type)
  391. GLenum type;
  392. {
  393.     glBegin(type);
  394. }
  395.  
  396. void
  397. myVertex(data)
  398. void *data;
  399. {
  400.     glVertex3fv((GLfloat *)data);
  401. }
  402.  
  403. void
  404. myEnd()
  405. {
  406.     glEnd();
  407. }
  408.  
  409. void
  410. myError(errnum)
  411. GLenum errnum;
  412. {
  413.     printf("myError %s \n",gluErrorString(errnum));
  414. }
  415.